/*
 * operonEnv.c
 *
 *  Created on: Sep 9, 2008
 *      Author: lindenb
 */
#include <assert.h>
#include "lang/morestdlib.h"
#include "util/debug.h"
#include "core/operonEnv.h"
#define CASTDEV(env) ((DB_ENV*)(env->dbenv))
#define FLAGS(flag,macro) flag |=(Properties_has(props,#macro,"true")?macro :(u_int32_t)0)

/** open envirronement */
OperonEnvPtr openronEnv_open()
	{
	char* path=getenv(OPERON_CFG_PATH);
	if(path==NULL)
		{
		DEBUG1("$"OPERON_CFG_PATH" was not defined");
		return NULL;
		}
	return openronEnv_fopen(path);
	}

OperonEnvPtr openronEnv_fopen(const char* configFileName)
	{
	char *db_home;
	int ret;
	OperonEnvPtr env=NULL;
	u_int32_t flags=(u_int32_t)0;
	Properties props;
	if(configFileName==NULL) return openronEnv_open();

	//read xml config
	props= Properties_read(configFileName);
	if(props==NULL) return NULL;
	//new Operon Structure
	env= (OperonEnvPtr)Malloc(sizeof(OperonEnv));
	if(env==NULL) return NULL;


	/// get the operon home directory
	env->_db_home = Properties_get(props,"db.home");
	if(env->_db_home==NULL);
		{
		//take the base directory of the xml confid
		env->_db_home= dirname(configFileName);
		}

	if(!fileExists(env->_db_home))
		{
		DEBUG2("File does not exists : %s .",env->_db_home);
		goto failure;
		}

	//parse the config flags
	FLAGS(flags,DB_RPCCLIENT);


	if ((ret = db_env_create(&(env->_dbenv),flags)) != 0)
		{
		DEBUG2("Cannot db_env_create %s",db_strerror(ret));
		goto failure;
		}

	/** "The DB_ENV handle contains a special field,
	 * "app_private", which is declared as type "void *".
	 * This field is provided for the use of the application program."
	 * link to 'this' */
	env->_dbenv->app_private= env;





	CASTDEV(dbenv)->open(
		CASTDEV(dbenv),
		dbenv->db_home,
		flags
		);

	Properties_delete(props);
	return env;
	//problem
	failure:
		Properties_delete(props);
		operonEnv_free(env);
	return NULL;
	}

DB_ENV* operonEnv_getBerkeleyPtr(OperonEnvPtr env)
	{
	assert(env!=NULL);
	return CASTDEV(env);
	}

void operonEnv_close(OperonEnvPtr env)
	{
	assert(env!=NULL);
	Free(env->_db_home);
	if(env->dbenv!=NULL) Free(env->dbenv);
	}

void operonEnv_delete(OperonEnvPtr env)
	{
	if(env==NULL) return;
	operonEnv_dispose(env);
	Free(env);
	}


#ifdef TEST_THIS_CODE

int main(int argc,char** argv)
    {
    return 0;
    }

#endif